package com.dhecp.project.storage.service.impl;

import com.alibaba.fastjson.JSON;
import com.dhecp.common.core.domain.AjaxResult;
import com.dhecp.common.utils.MessageUtils;
import com.dhecp.common.utils.RandomValueUtils;
import com.dhecp.common.utils.TypeUtils;
import com.dhecp.core.utils.PageUtils;
import com.dhecp.core.utils.ReflectUtils;
import com.dhecp.project.common.domain.ModuleNID;
import com.dhecp.project.common.domain.RecordCheck;
import com.dhecp.project.common.domain.UpdateFlow;
import com.dhecp.project.common.service.impl.BaseModuleServiceImpl;
import com.dhecp.project.storage.domain.*;
import com.dhecp.project.storage.enums.TailprogramEnum;
import com.dhecp.project.storage.mapper.*;
import com.dhecp.project.storage.service.HwReconcileService;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import com.dhecp.core.constant.DataFiltering;
import com.dhecp.project.system.service.SysDictionaryForFieldService;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 海外仓对账单(HwReconcile表)服务实现类
 *
 * @author fxz
 * @since 2024-02-29 16:40:35
 */
@Service("hwReconcileService")
public class HwReconcileServiceImpl extends BaseModuleServiceImpl implements HwReconcileService {
    @Autowired
    private HwReconcileMapper hwReconcileMapper;
    
    @Autowired
    private SysDictionaryForFieldService dictionaryForFieldService;

    @Autowired
    private DeliveryLogisticsMapper deliveryLogisticsMapper;

    @Autowired
    private HwStorageHistoryMapper hwStorageHistoryMapper;

    @Autowired
    private HwReconcileSonMapper hwReconcileSonMapper;

    @Autowired
    private HwReconcileCksonMapper hwReconcileCksonMapper;

    @Autowired
    private HwReconcileKcsonMapper hwReconcileKcsonMapper;

    @Autowired
    private HwTailprogramMapper hwTailprogramMapper;



    /**
    * 查询列表数据
    */
    @Override
    public List<HwReconcile> queryList(Map<String, Object> params) throws Exception{
        params.put(DataFiltering.TABLE_ALIAS, "t1");	//查询表别名
        params.put(DataFiltering.DATA_WHERE, dictionaryForFieldService.getWhereStr(params));	//常规查询条件SQL语句
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));	//数据权限查询条件SQL语句
        if (params.get("field") == null || params.get("field") == ""){
            String orderBy = "createTime asc";
            PageUtils.startPageOrder(orderBy);
        }else{
            PageUtils.startPage();
        }
        return this.hwReconcileMapper.select(params);
    }
    
        /**
     * 通过guid查询单条数据
     *
     * @param params 对象
     * @return 实例对象
     */
    @Override
    public HwReconcile queryFirstRecord(Map<String, Object> params) throws Exception{
        params.put(DataFiltering.TABLE_ALIAS, "t1");	//查询表别名
        params.put(DataFiltering.DATA_WHERE, dictionaryForFieldService.getWhereStr(params));	//常规查询条件SQL语句
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));	//数据权限查询条件SQL语句
        return this.hwReconcileMapper.selectFirstRecordByNid(params);
    }
    
    @SuppressWarnings("unchecked")
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult saveData(Map<String, Object> params) {
        params.put("businessEntity", new HwReconcile());
        AjaxResult ajaxResult = this.saveDataBase(params);

        Map<String, Object> infoMap = (Map<String, Object>) ajaxResult.get("infoMap");
        String resNid = infoMap.get("nid").toString();

        HwReconcile onData = JSON.parseObject(params.get("infoMap").toString(), HwReconcile.class);
        //判断有对过账的月份不允许
        int i = hwReconcileMapper.countHwMonthAndBidAndWarehouseAddress(onData);
        if (i > 0){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error(onData.getHwMonth()+"此月份已对账,请核实后在操作!");
        }
        List<HwReconcileKcson> hwReconcileKcsonList = new ArrayList<>();
        if (params.containsKey("infoItemsKc")){
            hwReconcileKcsonList = JSON.parseArray(params.get("infoItemsKc").toString(), HwReconcileKcson.class);
        }

        List<HwReconcileSon> onSonData = new ArrayList<>();
        if (params.containsKey("infoItems")){
            onSonData = JSON.parseArray(params.get("infoItems").toString(), HwReconcileSon.class);
        }
        List<HwReconcileCkson> hwReconcileCksonList= new ArrayList<>();
        if (params.containsKey("infoItemsCk")){
            hwReconcileCksonList = JSON.parseArray(params.get("infoItemsCk").toString(), HwReconcileCkson.class);
        }

        List<RecordCheck> guidMapList = hwReconcileMapper.findRecords(resNid);

        Map<String, Object> guidMap = new HashMap<String, Object>();
        if (!guidMapList.isEmpty()){
            if (infoMap.get("newNid") != null && "1".equals(infoMap.get("newNid").toString())){ //单号重复验证
                throw new RuntimeException(MessageUtils.message("module.error.retry"));
            }
            for (RecordCheck recordCheck : guidMapList){
                if (recordCheck != null && recordCheck.getGuid() != null){
                    guidMap.put(recordCheck.getGuid().toString(), "1");
                }
            }
        }
        if (onSonData == null || onSonData.size() == 0){
            resNid = "0";
        }else{
            resNid = infoMap.get("nid").toString();
            String guid = "";
            if (onData.getGuid() == null){
                guid = RandomValueUtils.getGUID();
                onData.setGuid(guid);
            }else{
                guid = onData.getGuid().toString();
            }

            for (String field : infoMap.keySet()) { //遍历非网格字段，并赋值到实体中
                Object fieldValue = infoMap.get(field);
                ReflectUtils.setValue(onData, field, fieldValue);
            }

            //对账总金额（实际）
            BigDecimal sjAmount = BigDecimal.ZERO;
            //对账总金额（系统）
            BigDecimal xtAmount = BigDecimal.ZERO;
            //计算总值
            for (HwReconcileSon hwReconcileSon : onSonData){
                sjAmount = sjAmount.add(hwReconcileSon.getSjRkAmount());
                xtAmount = xtAmount.add(hwReconcileSon.getXtRkAmount());
            }

            for (HwReconcileKcson hwReconcileKcson : hwReconcileKcsonList){
                sjAmount = sjAmount.add(hwReconcileKcson.getSjKcAmount());
                xtAmount = xtAmount.add(hwReconcileKcson.getXtKcAmount());
            }

            for (HwReconcileCkson hwReconcileCkson : hwReconcileCksonList){
                sjAmount = sjAmount.add(hwReconcileCkson.getSjCkAmount());
                xtAmount = xtAmount.add(hwReconcileCkson.getXtCkAmount());
            }


            onData.setSjAmount(sjAmount.setScale(2,BigDecimal.ROUND_HALF_UP));
            onData.setXtAmount(xtAmount.setScale(2,BigDecimal.ROUND_HALF_UP));
            if (guidMap.get(guid) == null){
                onData.setGuid(RandomValueUtils.getGUID());
                onData.setStateName(TailprogramEnum.StateName.CHECKINGACCOUNTS.value);
                hwReconcileMapper.insert(onData);
            }else{
                hwReconcileMapper.update(onData);
                guidMap.remove(guid);

                //删除详情
                hwReconcileKcsonMapper.deletePBid(onData.getBid());
                hwReconcileSonMapper.deletePBid(onData.getBid());

                Map<String, Object> params3 = new HashMap<String, Object>();
                params3.put("pBid",onData.getBid());

                List<HwReconcileCkson> hwReconcileCksonList1 = hwReconcileCksonMapper.select(params3);
                for (HwReconcileCkson hwReconcileCkson : hwReconcileCksonList1){
                    //已审核
                    hwTailprogramMapper.updateState(hwReconcileCkson.getWcBid(), TailprogramEnum.StateName.SUCCESS.value);
                }

                hwReconcileCksonMapper.deletePBid(onData.getBid());
            }

            //新增
            for (HwReconcileSon hwReconcileSon : onSonData){
                hwReconcileSon.setGuid(RandomValueUtils.getGUID());
                hwReconcileSon.setPBid(onData.getBid());
                hwReconcileSonMapper.insert(hwReconcileSon);
            }
            for (HwReconcileKcson hwReconcileKcson : hwReconcileKcsonList){
                hwReconcileKcson.setGuid(RandomValueUtils.getGUID());
                hwReconcileKcson.setPBid(onData.getBid());
                hwReconcileKcsonMapper.insert(hwReconcileKcson);
            }
            for (HwReconcileCkson hwReconcileCkson  : hwReconcileCksonList){
                hwReconcileCkson.setGuid(RandomValueUtils.getGUID());
                hwReconcileCkson.setPBid(onData.getBid());
                hwReconcileCksonMapper.insert(hwReconcileCkson);

                //尾程单对账中
                hwTailprogramMapper.updateState(hwReconcileCkson.getWcBid(), TailprogramEnum.StateName.CHECKINGACCOUNTS.value);
            }
        }

        if (!guidMap.isEmpty()) {
            for (String guid : guidMap.keySet()) {
                hwReconcileMapper.delete(guid);
                hwReconcileKcsonMapper.deletePBid(onData.getBid());
                hwReconcileSonMapper.deletePBid(onData.getBid());

                Map<String, Object> params3 = new HashMap<String, Object>();
                params3.put("pBid",onData.getBid());

                List<HwReconcileCkson> hwReconcileCksonList1 = hwReconcileCksonMapper.select(params3);
                for (HwReconcileCkson hwReconcileCkson : hwReconcileCksonList1){
                    //已审核
                    hwTailprogramMapper.updateState(hwReconcileCkson.getWcBid(), TailprogramEnum.StateName.SUCCESS.value);
                }

                hwReconcileCksonMapper.deletePBid(onData.getBid());

            }
        }

        return AjaxResult.success(MessageUtils.message("module.success.issuccess"),resNid);
    }
    
        /**
     *@Description: 退回  —— 添加流程任务、修改流程状态及生效标志
     *@Param: [params] tableDataId 必要参数：单据编码（nid）
     *@return: com.dhecp.common.core.domain.AjaxResult
     *@Author: fxz
     *@date: 2024-02-29 16:40:35
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult updateFlowBack(Map<String, Object> params) {
        Map<String, Object> infoMap = new HashMap<String, Object>();
        String nid = "0";
        if (params.get("tableDataId") == null || params.get("tableDataId") ==""){
            return AjaxResult.error(MessageUtils.message("module.error.lack","单据编码【tableDataId】"));
        }else{
            nid = params.get("tableDataId").toString();
        }
        params.put("nid", nid);
        List<HwReconcile> businessDataList = hwReconcileMapper.selectByNid(params);
        if (businessDataList == null || businessDataList.size() == 0){
            return AjaxResult.error(MessageUtils.message("module.error.nodata"));
        }else{
            infoMap.put("cid", businessDataList.get(0).getCid());
            infoMap.put("bUser", businessDataList.get(0).getbUser());
            infoMap.put("bDept", businessDataList.get(0).getbDept());
            infoMap.put("procInstId", businessDataList.get(0).getProcInstId());
            infoMap.put("activeFlow", businessDataList.get(0).getActiveFlow());
            infoMap.put("createTime", businessDataList.get(0).getCreateTime());
            params.put("infoMap", TypeUtils.mapToJson(infoMap).toString());
            params.put("activeFlowOld", businessDataList.get(0).getActiveFlow());
        }

        //流程处理公共方法，返回单据（流转、回退等）后的流程状态信息
        if (params.get("optType") == null || params.get("optType") == ""){
            params.put("optType", "back");
        }
        UpdateFlow updateFlow = new UpdateFlow();
        updateFlow = this.FlowDealBase(params);

        for (HwReconcile businessData : businessDataList) {
            updateFlow.setGuid(businessData.getGuid().toString());
            hwReconcileMapper.updateFlow(updateFlow);

            if (infoMap.get("activeFlow").equals("end")){
                Map<String, Object> params3 = new HashMap<String, Object>();
                params3.put("pBid",businessData.getBid());
                List<HwReconcileCkson> hwReconcileCksonList1 = hwReconcileCksonMapper.select(params3);
                for (HwReconcileCkson hwReconcileCkson : hwReconcileCksonList1){
                    //对账中
                    hwTailprogramMapper.updateState(hwReconcileCkson.getWcBid(), TailprogramEnum.StateName.CHECKINGACCOUNTS.value);
                }
                hwReconcileMapper.updateState(businessData.getBid(), TailprogramEnum.StateName.CHECKINGACCOUNTS.value);
            }
        }

        return AjaxResult.success(MessageUtils.message("module.success.issuccess"), nid);
    }
    
        /**
     *@Description: 流转  —— 添加流程任务、修改流程状态及生效标志
     *@Param: [params] tableDataId 必要参数：单据编码（nid）
     *@return: com.dhecp.common.core.domain.AjaxResult
     *@Author: fxz
     *@date: 2024-02-29 16:40:35
     */
    @Override
    @Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
    public AjaxResult updateFlowGo(Map<String, Object> params) {
        Map<String, Object> infoMap = new HashMap<String, Object>();
        String nid = "0";
        if (params.get("tableDataId") == null || params.get("tableDataId") ==""){
            return AjaxResult.error(MessageUtils.message("module.error.lack","单据编码【tableDataId】"));
        }else{
            nid = params.get("tableDataId").toString();
        }
        params.put("nid", nid);
        List<HwReconcile> businessDataList = hwReconcileMapper.selectByNid(params);
        if (businessDataList == null || businessDataList.size() == 0){
            return AjaxResult.error(MessageUtils.message("module.error.nodata"));
        }else{
            infoMap.put("cid", businessDataList.get(0).getCid());
            infoMap.put("bUser", businessDataList.get(0).getbUser());
            infoMap.put("bDept", businessDataList.get(0).getbDept());
            infoMap.put("procInstId", businessDataList.get(0).getProcInstId());
            infoMap.put("activeFlow", businessDataList.get(0).getActiveFlow());
            infoMap.put("createTime", businessDataList.get(0).getCreateTime());
            params.put("infoMap", TypeUtils.mapToJson(infoMap).toString());
            params.put("activeFlowOld", businessDataList.get(0).getActiveFlow());
        }

        //流程处理公共方法，返回单据（流转、回退等）后的流程状态信息
        if (params.get("optType") == null || params.get("optType") == ""){
            params.put("optType", "go");
        }

        UpdateFlow updateFlow = new UpdateFlow();
        updateFlow = this.FlowDealBase(params);

        for (HwReconcile businessData : businessDataList) {
            updateFlow.setGuid(businessData.getGuid().toString());
            hwReconcileMapper.updateFlow(updateFlow);

            if (updateFlow.getActiveFlow().equals("end")){
                Map<String, Object> params3 = new HashMap<String, Object>();
                params3.put("pBid",businessData.getBid());
                List<HwReconcileCkson> hwReconcileCksonList1 = hwReconcileCksonMapper.select(params3);
                for (HwReconcileCkson hwReconcileCkson : hwReconcileCksonList1){
                    //已对账
                    hwTailprogramMapper.updateState(hwReconcileCkson.getWcBid(), TailprogramEnum.StateName.HAVERECONCILED.value);
                }

                hwReconcileMapper.updateState(businessData.getBid(), TailprogramEnum.StateName.HAVERECONCILED.value);
            }
        }
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"), nid);
    }
    
        /**
     *@Description: 查询前一单NID、BID
     *@Param: [params] nid 必要参数：当前 单据编码
     *@return: com.dhecp.common.core.domain.AjaxResult  (data.nid 前一单NID， data.bid 前一单BID)
     *@Author: fxz
     *@date: 2024-02-29 16:40:35
     */
    @Override
    public AjaxResult queryLastNid(Map<String, Object> params) throws Exception {
        Map<String, Object> dataMap = new HashMap<String, Object>();
        if (params.get("nid") == null || params.get("nid") == ""){
            params.put("nid", "0");
        }
        params.put(DataFiltering.TABLE_ALIAS, "t1");	//查询表别名
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));	//数据权限查询条件SQL语句
        ModuleNID moduleNID = hwReconcileMapper.selectLastNid(params);
        if (moduleNID == null){
            dataMap.put("nid", "0");
            dataMap.put("bid", "0");
            return AjaxResult.warn(MessageUtils.message("module.warn.isfirstnid"), TypeUtils.mapToJson(dataMap).toString());
        }
        dataMap.put("nid", moduleNID.getNid().toString());
        dataMap.put("bid", moduleNID.getBid().toString());
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"), TypeUtils.mapToJson(dataMap).toString());
    }


    /**
     *@Description: 查询后一单NID、BID
     *@Param: [params] nid 必要参数：当前 单据编码
     *@return: com.dhecp.common.core.domain.AjaxResult  (data.nid 后一单NID， data.bid 后一单BID)
     *@Author: fxz
     *@date: 2024-02-29 16:40:35
     */
    @Override
    public AjaxResult queryNextNid(Map<String, Object> params) throws Exception {
        Map<String, Object> dataMap = new HashMap<String, Object>();
        if (params.get("nid") == null || params.get("nid") == "" || "0".equals(params.get("nid").toString())){
            dataMap.put("nid", "0");
            dataMap.put("bid", "0");
            return AjaxResult.warn(MessageUtils.message("module.warn.isfinallynid"), TypeUtils.mapToJson(dataMap).toString());
        }
        params.put(DataFiltering.TABLE_ALIAS, "t1");	//查询表别名
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));	//数据权限查询条件SQL语句
        ModuleNID moduleNID = hwReconcileMapper.selectNextNid(params);
        if (moduleNID == null){
            dataMap.put("nid", "0");
            dataMap.put("bid", "0");
            return AjaxResult.warn(MessageUtils.message("module.warn.isfinallynid"), TypeUtils.mapToJson(dataMap).toString());
        }
        dataMap.put("nid", moduleNID.getNid().toString());
        dataMap.put("bid", moduleNID.getBid().toString());
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"), TypeUtils.mapToJson(dataMap).toString());
    }


    /**
     *@Description: 子件数据
     *@Author: fxz
     *@date: 2024-03-01 11:09:34
     */
    @Override
    public AjaxResult sonList(Map<String, Object> params) {
        String[] hwMonthList = params.get("hwMonth").toString().split("-");
        if (hwMonthList.length != 1){
            AjaxResult.error("数据异常!");
        }
        String year = hwMonthList[0];
        String mouth = hwMonthList[1];
        //入库对账信息
        List<HwReconcileSon> hwReconcileSonList = deliveryLogisticsMapper.listDateAndOverseasName(year,mouth, params.get("warehouseAddress").toString());
        //库存对账信息
        List<HwReconcileKcson> hwReconcileKcsonList = hwStorageHistoryMapper.listDateAndOverseasName(year,mouth, params.get("warehouseAddress").toString());
        //出库对账信息
        List<HwReconcileCkson> hwReconcileCksonList = hwTailprogramMapper.listDateAndOverseasName(year,mouth, params.get("warehouseAddress").toString());

        params.put("hwReconcileSonList",hwReconcileSonList);
        params.put("hwReconcileKcsonList",hwReconcileKcsonList);
        params.put("hwReconcileCksonList",hwReconcileCksonList);
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"), params);
    }

    /**
     * 海外付款调用数据
     * @param params
     * @return
     * @throws Exception
     */
    @Override
    public List<HwReconcileSelect> queryListSelect(Map<String, Object> params) throws Exception {
        params.put(DataFiltering.TABLE_ALIAS, "t1");	//查询表别名
        params.put(DataFiltering.DATA_WHERE, dictionaryForFieldService.getWhereStr(params));	//常规查询条件SQL语句
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));	//数据权限查询条件SQL语句

        PageUtils.startPage();

        return hwReconcileMapper.queryListSelect(params);
    }
}

